home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
076-100
/
scopedisk89
/
watcher2
/
watcher2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-19
|
7KB
|
261 lines
/*
* Watcher.c - A silly little program inspired by a second-hand description
* of a probably just as silly program on Sun workstations.
*
* Author : Andrew Folkins
* (CIS : 72060,740 UUCP : ...!alberta!edm!cuenews!andrew)
*
* Date : March 22, 1989
*
* Version : 0.1
*
* Language : Lattice C 5.02 - compile with -Lt -v
*
* Legalese : Public Domain. Permission is hereby granted to bend, fold
* spindle or mutilate this code in any way you see fit.
*
* If you feel ambitious, here's a few things you can try :
* - Make the movement smoother. The big problem right now is erasing
* the previous rendering, which allows the white background to
* flash through. The proper way to do this is to render everything
* off screen then BltBitMapRastPort() or whatever.
* - Add eyelids. The watcher should go to sleep if nothing happens
* for a while. Of course, he might also peek through one eye
* every now and then to see what's going on.
* - Get rid of the window border, and make the system gadgets invisible.
*/
/*
* Modified by Mike Topf to add sleep with non activity.
* Also removed part of the border.
*/
#include <exec/types.h>
#include <graphics/rastport.h>
#include <graphics/gfxmacros.h>
#include <intuition/intuition.h>
#include <intuition/preferences.h>
#include <intuition/intuitionbase.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/exec.h>
static char *ForHexDumpers = "Watcher 0.1 by Andrew Folkins (Public Domain)";
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
#define WIDTH 105
#define HEIGHT 32
struct NewWindow newwindow = {
100, 10, WIDTH, HEIGHT,
-1, -1,
CLOSEWINDOW,
WINDOWCLOSE | WINDOWDRAG | BORDERLESS | NOCAREREFRESH,
NULL, /* Gadget list */
NULL, /* Checkmark */
NULL, /* Title */
NULL, /* Screen */
NULL, /* Bitmap */
0, 0, 0, 0, /* minwidth, minheight, maxwidth , maxheight */
WBENCHSCREEN
};
struct Window *window;
short PrefsX, PrefsY, /* Offset of the pointer hotspot */
OfsX, OfsY, /* Approximate distance from eye to pointer */
EyeColor;
/* Yow! Area fills! Warning - the magic numbers may not be quite right */
WORD buffer[75];
struct AreaInfo AreaInfo;
struct TmpRas TmpRas;
#define RASWIDTH 80
#define RASHEIGHT 40
PLANEPTR raster;
void CloseStuff()
{
if (raster) FreeRaster(raster, RASWIDTH, RASHEIGHT);
if (window) CloseWindow(window);
if (GfxBase) CloseLibrary((struct Library *)GfxBase);
if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
_exit(0);
}
void OpenStuff()
{
struct Preferences pref;
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
if (!IntuitionBase) CloseStuff();
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0);
if (!GfxBase) CloseStuff();
window = OpenWindow(&newwindow);
if (!window) CloseStuff();
raster = AllocRaster(RASWIDTH, RASHEIGHT);
if (!raster) CloseStuff();
/* Get the offset of the pointer's 'hot spot'. */
GetPrefs(&pref, sizeof(struct Preferences));
PrefsX = pref.XOffset;
PrefsY = pref.YOffset;
window->RPort->TmpRas = InitTmpRas(&TmpRas, raster, RASSIZE(RASWIDTH, RASHEIGHT));
/* Pick a semi-random eye color */
/* I changed it to a constant colour since the long pupil looked better */
EyeColor = 3;
}
/* From "Assembler Language Programming S/370", 2nd Ed, by Struble, pg 341 */
long sqrt(n)
long n;
{
long x0, x1;
x0 = (1 + n) / 2;
for (;;) { /* A vaguely Newton-ish iteration */
x1 = x0 + ((n / x0) - x0) / 2;
if (x1 >= x0) return(x1);
x0 = x1;
}
}
/* Store previous position */
short left[2] = {30, 20},
right[2] = {75, 20};
void DrawEye(ex, ey, position)
short ex, ey, *position;
{
long dx, dy, t, oldex, oldey;
/* First figure out where we're supposed to be looking */
oldex = ex;
oldey = ey;
dx = ex + OfsX;
dy = ey + OfsY;
t = dx * dx + dy * dy;
if (t > 25) {
t = sqrt(t);
dx = 5 * dx / t;
dy = 5 * dy / t;
}
ex -= dx * 2;
ey -= dy;
/* If we have a new position, redraw the eye */
if (ex != position[0] || ey != position[1]) {
/* Draw the background */
InitArea(&AreaInfo, (short *)buffer, 15);
SetAPen(window->RPort, 1);
AreaEllipse(window->RPort, oldex, oldey, 21, 10);
AreaEnd(window->RPort);
/* Draw the iris */
InitArea(&AreaInfo, (short *)buffer, 15);
SetAPen(window->RPort, EyeColor);
AreaEllipse(window->RPort, ex, ey, 10, 5);
AreaEnd(window->RPort);
/* Draw the pupil */
InitArea(&AreaInfo, (short *)buffer, 15);
SetAPen(window->RPort, 2);
AreaEllipse(window->RPort, ex, ey, t/40, 4);
AreaEnd(window->RPort);
position[0] = ex;
position[1] = ey;
}
}
void DrawWatcher()
{
SetDrMd(window->RPort, JAM1);
window->RPort->AreaInfo = &AreaInfo;
DrawEye(30, 20, left);
DrawEye(75, 20, right);
}
void DrawClose(ex, ey)
short ex, ey;
{
/* Draw the background */
InitArea(&AreaInfo, (short *)buffer, 15);
SetAPen(window->RPort, 1);
AreaEllipse(window->RPort, ex, ey, 21, 10);
AreaEnd(window->RPort);
/* Draw Eyelid closed */
InitArea(&AreaInfo, (short *)buffer, 15);
SetAPen(window->RPort, 2);
AreaEllipse(window->RPort, ex, ey, 21, 0);
AreaEnd(window->RPort);
}
void DrawSleeper()
{
SetDrMd(window->RPort, JAM1);
window->RPort->AreaInfo = &AreaInfo;
DrawClose(30, 20);
DrawClose(75, 20);
}
void DoMessages()
{
struct IntuiMessage *message;
ULONG class;
SHORT mousex, mousey, time1;
struct Screen *screen;
screen = window->WScreen;
mousex = 0;
mousey = 0;
time1 = 0; /* set the sleep counters */
for (;;) { /* Excuse the polling, but . . . */
time1 = time1 + 1;
/* check to see if needs sleep */
if (time1 == 1024) {
DrawSleeper();
}
Delay(2);
if (mousex != screen->MouseX || mousey != screen->MouseY) {
mousex = screen->MouseX;
mousey = screen->MouseY;
OfsX = window->LeftEdge - (mousex - PrefsX);
OfsY = window->TopEdge - (mousey - PrefsY);
DrawWatcher();
time1 = 0;
}
while (message = (struct IntuiMessage *)GetMsg(window->UserPort)) {
class = message->Class;
ReplyMsg((struct Message *)message);
if (class == CLOSEWINDOW)
return;
}
}
}
void _main()
{
OpenStuff();
DoMessages();
CloseStuff();
}